{
 "cells": [
  {
   "cell_type": "code",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2024-12-27T08:45:58.271791Z",
     "start_time": "2024-12-27T08:45:56.868130Z"
    }
   },
   "source": [
    "# MAE: 528.190\n",
    "# XGBoostRegressor\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.model_selection import KFold\n",
    "from sklearn.metrics import mean_absolute_error\n",
    "from xgboost import XGBRegressor\n",
    "import xgboost as xgb\n",
    "\n",
    "train = pd.read_csv('../Data/used_car_train_20200313.csv', sep=' ')\n",
    "test = pd.read_csv('../Data/used_car_testB_20200421.csv', sep=' ')\n",
    "\n",
    "# 合并训练数据和测试数据集\n",
    "all_data = pd.concat([train, test], ignore_index=True)\n",
    "\n",
    "# 对 price 做对数变换\n",
    "all_data['price'] = np.log1p(all_data['price'])"
   ],
   "outputs": [],
   "execution_count": 1
  },
  {
   "cell_type": "code",
   "source": [
    "# 处理异常值，如功率大于 600 的值\n",
    "all_data['power'] = all_data['power'].apply(lambda x: 600 if x > 600 else x)\n",
    "\n",
    "# 处理日期相关信息\n",
    "all_data['reg_year'] = all_data['regDate'].apply(lambda x: int(str(x)[:4]))\n",
    "all_data['reg_month'] = all_data['regDate'].apply(lambda x: int(str(x)[4:6]))\n",
    "all_data['reg_day'] = all_data['regDate'].apply(lambda x: int(str(x)[6:]))\n",
    "all_data['creat_year'] = all_data['creatDate'].apply(lambda x: int(str(x)[:4]))\n",
    "all_data['creat_month'] = all_data['creatDate'].apply(lambda x: int(str(x)[4:6]))\n",
    "all_data['creat_day'] = all_data['creatDate'].apply(lambda x: int(str(x)[6:]))\n",
    "\n",
    "# 标记汽车没有经过维修\n",
    "all_data['notRepairedDamage'] = all_data['notRepairedDamage'].apply(lambda x: 0 if x == '-' else 1)\n",
    "\n",
    "# 对可分类的连续特征进行分桶，如将功率（power）分成10个分桶，并提取新特征\n",
    "all_data['power_bucket'] = pd.cut(all_data['power'], 10, labels=False)\n",
    "new_cols = ['power_bucket', 'v_0', 'v_3', 'v_8', 'v_12']\n",
    "for col1 in new_cols:\n",
    "    for col2 in new_cols:\n",
    "        if col1 != col2:\n",
    "            all_data['{}_{}_sum'.format(col1, col2)] = all_data[col1] + all_data[col2]\n",
    "            all_data['{}_{}_diff'.format(col1, col2)] = all_data[col1] - all_data[col2]\n",
    "\n",
    "# 处理缺失值\n",
    "all_data['fuelType'] = all_data['fuelType'].fillna(0)\n",
    "all_data['gearbox'] = all_data['gearbox'].fillna(0)\n",
    "all_data['bodyType'] = all_data['bodyType'].fillna(0)\n",
    "all_data['model'] = all_data['model'].fillna(0)\n",
    "\n",
    "# 分离特征和标签\n",
    "train_data = all_data[~all_data['price'].isnull()]\n",
    "test_data = all_data[all_data['price'].isnull()]\n",
    "X_train = train_data.drop(['SaleID', 'name', 'regDate', 'creatDate', 'price'], axis=1)\n",
    "X_test = test_data.drop(['SaleID', 'name', 'regDate', 'creatDate', 'price'], axis=1)\n",
    "y_train = train_data['price']"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-12-27T08:45:58.844897Z",
     "start_time": "2024-12-27T08:45:58.282874Z"
    }
   },
   "outputs": [],
   "execution_count": 2
  },
  {
   "cell_type": "code",
   "source": [
    "# 定义模型参数\n",
    "dtrain = xgb.DMatrix(X_train, label=y_train)\n",
    "dtest = xgb.DMatrix(X_test)\n",
    "\n",
    "params = {\n",
    "    'max_depth': 10,\n",
    "    'learning_rate': 0.05,\n",
    "    'num_boost_round': 1000,\n",
    "    'gamma': 0.005,\n",
    "    'subsample': 0.9,\n",
    "    'colsample_bytree': 0.7,\n",
    "    'objective': 'reg:squarederror',\n",
    "    'random_state': 2021,\n",
    "    'eval_metric': 'mae'\n",
    "}\n",
    "\n",
    "skf = KFold(n_splits=5, shuffle=True, random_state=2021)\n",
    "oof = np.zeros(len(X_train))\n",
    "test_predict = np.zeros(len(X_test))\n",
    "\n",
    "for i, (train_index, val_index) in enumerate(skf.split(X_train, y_train)):\n",
    "    print(\"Training on Fold {}\".format(i+1))\n",
    "    tr_x, tr_y = X_train.iloc[train_index], y_train.iloc[train_index]\n",
    "    vl_x, vl_y = X_train.iloc[val_index], y_train.iloc[val_index]\n",
    "\n",
    "    dtrain_fold = xgb.DMatrix(tr_x, label=tr_y)\n",
    "    dval_fold = xgb.DMatrix(vl_x, label=vl_y)\n",
    "\n",
    "    watchlist = [(dtrain_fold, 'train'), (dval_fold, 'eval')]\n",
    "    num_round = 1000\n",
    "    bst_model = xgb.train(params, dtrain_fold, num_round, watchlist, early_stopping_rounds=100, verbose_eval=200)\n",
    "\n",
    "    oof[val_index] = bst_model.predict(dval_fold)\n",
    "    test_predict += bst_model.predict(dtest) / skf.n_splits\n",
    "\n",
    "mae = mean_absolute_error(np.expm1(y_train), np.expm1(oof))\n",
    "\n",
    "print(\"MAE: {:.3f}\".format(mae))\n",
    "\n",
    "# 保存预测结果\n",
    "submission = pd.DataFrame({'SaleID': test_data['SaleID'], 'price': np.expm1(test_predict)})\n",
    "\n",
    "submission.to_csv('xgb_submission.csv', index=False)\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-12-27T08:46:34.305478Z",
     "start_time": "2024-12-27T08:45:58.954355Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training on Fold 1\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\python\\Lib\\site-packages\\xgboost\\core.py:723: FutureWarning: Pass `evals` as keyword args.\n",
      "  warnings.warn(msg, FutureWarning)\n",
      "D:\\python\\Lib\\site-packages\\xgboost\\core.py:158: UserWarning: [16:45:59] WARNING: C:\\buildkite-agent\\builds\\buildkite-windows-cpu-autoscaling-group-i-0c55ff5f71b100e98-1\\xgboost\\xgboost-ci-windows\\src\\learner.cc:740: \n",
      "Parameters: { \"num_boost_round\" } are not used.\n",
      "\n",
      "  warnings.warn(smsg, UserWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0]\ttrain-mae:0.94671\teval-mae:0.94409\n",
      "[200]\ttrain-mae:0.08540\teval-mae:0.12823\n",
      "[400]\ttrain-mae:0.06202\teval-mae:0.12501\n",
      "[600]\ttrain-mae:0.04698\teval-mae:0.12352\n",
      "[800]\ttrain-mae:0.03676\teval-mae:0.12279\n",
      "[999]\ttrain-mae:0.03142\teval-mae:0.12241\n",
      "Training on Fold 2\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\python\\Lib\\site-packages\\xgboost\\core.py:723: FutureWarning: Pass `evals` as keyword args.\n",
      "  warnings.warn(msg, FutureWarning)\n",
      "D:\\python\\Lib\\site-packages\\xgboost\\core.py:158: UserWarning: [16:46:29] WARNING: C:\\buildkite-agent\\builds\\buildkite-windows-cpu-autoscaling-group-i-0c55ff5f71b100e98-1\\xgboost\\xgboost-ci-windows\\src\\learner.cc:740: \n",
      "Parameters: { \"num_boost_round\" } are not used.\n",
      "\n",
      "  warnings.warn(smsg, UserWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0]\ttrain-mae:0.94562\teval-mae:0.94817\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mKeyboardInterrupt\u001B[0m                         Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[3], line 31\u001B[0m\n\u001B[0;32m     29\u001B[0m watchlist \u001B[38;5;241m=\u001B[39m [(dtrain_fold, \u001B[38;5;124m'\u001B[39m\u001B[38;5;124mtrain\u001B[39m\u001B[38;5;124m'\u001B[39m), (dval_fold, \u001B[38;5;124m'\u001B[39m\u001B[38;5;124meval\u001B[39m\u001B[38;5;124m'\u001B[39m)]\n\u001B[0;32m     30\u001B[0m num_round \u001B[38;5;241m=\u001B[39m \u001B[38;5;241m1000\u001B[39m\n\u001B[1;32m---> 31\u001B[0m bst_model \u001B[38;5;241m=\u001B[39m \u001B[43mxgb\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mtrain\u001B[49m\u001B[43m(\u001B[49m\u001B[43mparams\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mdtrain_fold\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mnum_round\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mwatchlist\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mearly_stopping_rounds\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;241;43m100\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mverbose_eval\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;241;43m200\u001B[39;49m\u001B[43m)\u001B[49m\n\u001B[0;32m     33\u001B[0m oof[val_index] \u001B[38;5;241m=\u001B[39m bst_model\u001B[38;5;241m.\u001B[39mpredict(dval_fold)\n\u001B[0;32m     34\u001B[0m test_predict \u001B[38;5;241m+\u001B[39m\u001B[38;5;241m=\u001B[39m bst_model\u001B[38;5;241m.\u001B[39mpredict(dtest) \u001B[38;5;241m/\u001B[39m skf\u001B[38;5;241m.\u001B[39mn_splits\n",
      "File \u001B[1;32mD:\\python\\Lib\\site-packages\\xgboost\\core.py:726\u001B[0m, in \u001B[0;36mrequire_keyword_args.<locals>.throw_if.<locals>.inner_f\u001B[1;34m(*args, **kwargs)\u001B[0m\n\u001B[0;32m    724\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m k, arg \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28mzip\u001B[39m(sig\u001B[38;5;241m.\u001B[39mparameters, args):\n\u001B[0;32m    725\u001B[0m     kwargs[k] \u001B[38;5;241m=\u001B[39m arg\n\u001B[1;32m--> 726\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mfunc\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32mD:\\python\\Lib\\site-packages\\xgboost\\training.py:181\u001B[0m, in \u001B[0;36mtrain\u001B[1;34m(params, dtrain, num_boost_round, evals, obj, feval, maximize, early_stopping_rounds, evals_result, verbose_eval, xgb_model, callbacks, custom_metric)\u001B[0m\n\u001B[0;32m    179\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m cb_container\u001B[38;5;241m.\u001B[39mbefore_iteration(bst, i, dtrain, evals):\n\u001B[0;32m    180\u001B[0m     \u001B[38;5;28;01mbreak\u001B[39;00m\n\u001B[1;32m--> 181\u001B[0m \u001B[43mbst\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mupdate\u001B[49m\u001B[43m(\u001B[49m\u001B[43mdtrain\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43miteration\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mi\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mfobj\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mobj\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    182\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m cb_container\u001B[38;5;241m.\u001B[39mafter_iteration(bst, i, dtrain, evals):\n\u001B[0;32m    183\u001B[0m     \u001B[38;5;28;01mbreak\u001B[39;00m\n",
      "File \u001B[1;32mD:\\python\\Lib\\site-packages\\xgboost\\core.py:2101\u001B[0m, in \u001B[0;36mBooster.update\u001B[1;34m(self, dtrain, iteration, fobj)\u001B[0m\n\u001B[0;32m   2097\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_assign_dmatrix_features(dtrain)\n\u001B[0;32m   2099\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m fobj \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m   2100\u001B[0m     _check_call(\n\u001B[1;32m-> 2101\u001B[0m         \u001B[43m_LIB\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mXGBoosterUpdateOneIter\u001B[49m\u001B[43m(\u001B[49m\n\u001B[0;32m   2102\u001B[0m \u001B[43m            \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mhandle\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mctypes\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mc_int\u001B[49m\u001B[43m(\u001B[49m\u001B[43miteration\u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mdtrain\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mhandle\u001B[49m\n\u001B[0;32m   2103\u001B[0m \u001B[43m        \u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m   2104\u001B[0m     )\n\u001B[0;32m   2105\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m   2106\u001B[0m     pred \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mpredict(dtrain, output_margin\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m, training\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m)\n",
      "\u001B[1;31mKeyboardInterrupt\u001B[0m: "
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": ""
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
